package com.mida.bms.report.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mida.bms.report.common.cons.ReportConst;
import com.mida.bms.report.common.massert.MRAssert;
import com.mida.bms.report.entity.*;
import com.mida.bms.report.enumdata.CriticalValueStatus;
import com.mida.bms.report.enumdata.ReportProcessStatus;
import com.mida.bms.report.mapper.*;
import com.mida.bms.report.service.DocReportCriticalService;
import com.mida.bms.report.service.SoidService;
import com.mida.bms.report.service.SrvDocReportService;
import com.mida.bms.report.vo.*;
import com.mida.tool.common.result.ActionResult;
import com.mida.tool.common.result.BaseResult;
import com.mida.tool.common.result.ListResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.List;

@Service
@Transactional
@Slf4j
public class DocReportCriticalServiceImpl extends BaseResult implements DocReportCriticalService {

    // ID生成器
    @Autowired
    private SoidService soidService;

    @Autowired
    private SrvDocReportService srvDocReportService;

    @Autowired
    private DocFeedbackContentMapper docFeedbackContentMapper;

    // 报告自定义文本
    @Autowired
    private DocCustomerContentMapper docCustomerContentMapper;

    @Autowired
    private DocCriticalDescMapper docCriticalDescMapper;

    // ---报告部分---
    // 报告危急值
    @Autowired
    private DocReportCriticalValueMapper docReportCriticalValueMapper;


    // 报告存储信息
    @Autowired
    private DocStructReportMapper docStructReportMapper;

    /**
     * 危急值接收(提供给外部代理使用)
     *
     * @param request
     * @return
     */
    @Override
    public ListResult recieveCriticalValue(CriticalValueRecieveRequest request) {
        ListResult listResult = new ListResult();
        try {
            MRAssert.massertNotEmpty(request.getDocReportCritivalValueSoid(), ReportConst.ReportErr.Empty.CRITICAL_ID);

            DocCriticalDesc docCriticalDesc = docCriticalDescMapper.selectByDocReportCriticalValueSoid(request.getDocReportCritivalValueSoid());
            if (docCriticalDesc != null) {
                docCriticalDesc.setReciever(request.getReciever());
                docCriticalDesc.setReceiveDeptSoid(request.getRecieveDeptSoid());
                docCriticalDesc.setRecievingDateTime(new Date());
                docCriticalDescMapper.updateByPrimaryKeySelective(docCriticalDesc);
            }
            DocReportCriticalValue docReportCriticalValue = docReportCriticalValueMapper.selectByPrimaryKey(request.getDocReportCritivalValueSoid());
            if (docReportCriticalValue != null) {
                // 已接收
                docReportCriticalValue.setStatus(CriticalValueStatus.RECEIVED.code);
                docReportCriticalValueMapper.updateByPrimaryKeySelective(docReportCriticalValue);
            }

            buildListSuccess(listResult);
        } catch (Exception e) {
            log.error("危急值接收异常", e);
            buildListWarn(listResult, "危急值接收发送失败");
        }
        return listResult;
    }

    /**
     * 危急值反馈(提供给外部代理使用)
     *
     * @param request
     * @return
     */
    @Override
    public ListResult feedbackCriticalValue(CriticalValueFeedbackRequest request) {
        ListResult listResult = new ListResult();
        try {
            MRAssert.massertNotEmpty(request.getDocReportCritivalValueSoid(), ReportConst.ReportErr.Empty.CRITICAL_ID);

            DocReportCriticalValue docReportCriticalValue = docReportCriticalValueMapper.selectByPrimaryKey(request.getDocReportCritivalValueSoid());
            if (docReportCriticalValue != null) {
                docReportCriticalValue.setFeedbackPersonSoid(request.getFeedBackPersonSoid());
                docReportCriticalValue.setFeedbackPersonName(request.getFeedBackPersonName());
                docReportCriticalValue.setFeedbackDeptSoid(request.getFeedBackDeptSoid());
                docReportCriticalValue.setFeedbackDateTime(new Date());
                // 已处理
                docReportCriticalValue.setStatus(CriticalValueStatus.PROCESSED.code);
                docReportCriticalValueMapper.updateByPrimaryKeySelective(docReportCriticalValue);

                DocFeedbackContent feedbackContent = new DocFeedbackContent();
                feedbackContent.setFeedbackContentSoid(soidService.getSoid());
                feedbackContent.setFeedbackContent(request.getFeedBackContent());
                feedbackContent.setCreateDate(new Date());
                feedbackContent.setUpdateDate(new Date());
                feedbackContent.setIsDelete(0L);
                feedbackContent.setReportCriticalValueSoid(docReportCriticalValue.getReportCriticalValueSoid());
                docFeedbackContentMapper.insert(feedbackContent);
            }

            buildListSuccess(listResult);
        } catch (Exception e) {
            log.error("危急值反馈异常", e);
            buildListWarn(listResult, "危急值反馈发送失败");
        }
        return listResult;
    }

    /**
     * 修改危急值主表状态为已发送
     *
     * @param docReportCritivalValueSoid
     * @return
     */
    @Override
    public ActionResult sentCriticalValue(Long docReportCritivalValueSoid) {
        ActionResult actionResult = new ActionResult();
        log.info("开始修改危急值主表状态为已发送");
        DocReportCriticalValue docReportCriticalValue = docReportCriticalValueMapper.selectByPrimaryKey(docReportCritivalValueSoid);
        if (docReportCriticalValue != null) {
            docReportCriticalValue.setStatus(CriticalValueStatus.SENT.code);
            docReportCriticalValue.setUpdateDate(new Date());
            // 已发送
            docReportCriticalValueMapper.updateByPrimaryKeySelective(docReportCriticalValue);
            buildActionSuccess(actionResult);
        } else {
            buildActionWarn(actionResult, "未找到危急值主表");
        }
        return actionResult;
    }

    /**
     * 保存危急值并转发
     *
     * @param request
     * @return
     */
    @Override
    public ListResult<Long> saveCritivalValue(CriticalValueRequest request) {
        log.info("开始保存危急值");
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult listResult = new ListResult();

        try {
            DocStructReport docStructReport = null;
            // 危急值校验
            if (StringUtils.isEmpty(request.getCriticalValueDesc())) {
                buildBadRequestListWarn(listResult, "危急值描述不能为空");
                return listResult;
            } else {
                if (ObjectUtils.isNotEmpty(request.getStReportSoid())) {
                    docStructReport = docStructReportMapper.selectByPrimaryKey(request.getStReportSoid());
                    if (ObjectUtils.isEmpty(docStructReport)) {
                        buildBadRequestListWarn(listResult, "报告不存在");
                        return listResult;
                    } else {
                        if (ObjectUtils.isNotEmpty(docStructReport.getReportCriticalValueSoid())) {
                            buildBadRequestListWarn(listResult, "危急值已上传,不能重复提交");
                            return listResult;
                        }
                    }
                }
            }

            // 报告危急值主表
            DocReportCriticalValue docReportCriticalValue = new DocReportCriticalValue();
            Long reportCriticalValueSoid = soidService.getSoid();
            docReportCriticalValue.setReportCriticalValueSoid(reportCriticalValueSoid);
            if (ObjectUtils.isNotEmpty(request.getApntPersonSoid())) {
                docReportCriticalValue.setApntPersonSoid(request.getApntPersonSoid());
            }
            if (ObjectUtils.isNotEmpty(request.getSubmitDeptSoid())) {
                // 提交科室标识
                docReportCriticalValue.setSubmitDeptSoid(request.getSubmitDeptSoid());
            }
            docReportCriticalValue.setSubmitter(request.getEmployeeSoid());
            docReportCriticalValue.setSubmitDateTime(new Date());
            docReportCriticalValue.setCreateDate(new Date());
            docReportCriticalValue.setUpdateUser(request.getEmployeeSoid());
            docReportCriticalValue.setUpdateDate(new Date());
            docReportCriticalValue.setIsDelete(0L);
            // 未发送
            docReportCriticalValue.setStatus(CriticalValueStatus.UNSENT.code);
            docReportCriticalValueMapper.insert(docReportCriticalValue);

            // 报告危急值描述
            DocCriticalDesc docCriticalDesc = new DocCriticalDesc();
            docCriticalDesc.setCriticalDescsSoid(soidService.getSoid());
            docCriticalDesc.setCriticalDesc(request.getCriticalValueDesc());
            docCriticalDesc.setReportCriticalValueSoid(reportCriticalValueSoid);
            docCriticalDesc.setCreateDate(new Date());
            docCriticalDesc.setUpdateDate(new Date());
            docCriticalDesc.setUpdateUser(request.getEmployeeSoid());
            docCriticalDesc.setCreator(request.getEmployeeSoid());
            docCriticalDesc.setIsDelete(0L);
            docCriticalDescMapper.insert(docCriticalDesc);

            //修改报告主表危急值标识
            docStructReport.setReportCriticalValueSoid(reportCriticalValueSoid);
            docStructReport.setUpdateDate(new Date());
            srvDocReportService.updateStructReportSelective(docStructReport);

            buildListSuccess(listResult, reportCriticalValueSoid);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("保存危急值发送异常", e);
            buildListWarn(listResult, "保存危急值");
        } finally {
            stopWatch.stop();
            log.info("本次保存危急值耗时: " + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

}
